using System.Collections.Generic;
using Configs;
using Inputs;
using Mgrs;
using Modules.Game.Enemies;
using Modules.Game.Roles;
using Modules.GameOver;
using Modules.Set;
using Modules.Tip;
using UnityEngine;
using UnityEngine.Pool;
using UnityEngine.SceneManagement;
using Utils;

namespace Modules.Game
{
    public class GameModule : MainManager<GameModule>
    {
        public GameObject enemyPrefab;
        public GameObject enemyPanel;
        public GameObject hero;

        private readonly List<GameObject> _enemys = new();

        private void Awake()
        {
            PoolManager.Instance.EnemyPool = new ObjectPool<GameObject>(CreateEnemy, GetEnemy, ReleaseEnemy);

            UIInput.Instance.OpenSetPanelAction += OnOpenSetPanel;
        }

        private void Update()
        {
            if (!GameModel.Instance.IsGaming) return;

            CheckEnemys();
        }

        protected override void OnDestroy()
        {
            base.OnDestroy();

            if (UIInput.IsExist) UIInput.Instance.OpenSetPanelAction -= OnOpenSetPanel;
        }

        public static void LoadModule()
        {
            SceneManager.LoadScene("GameScene");
        }

        protected override void LaunchInDevelopingMode()
        {
            // 开发逻辑
            GUIManager.SetResolution(1920, 1080, 0.0f);

            GUIManager.LoadPanel(nameof(GamePanel), UILayer.Common);

            GUIManager.LoadPanel(nameof(TipPanel), UILayer.Top);
        }

        protected override void LaunchInTestMode()
        {
            // 测试逻辑
            GUIManager.SetResolution(1920, 1080, 0.0f);

            GUIManager.LoadPanel(nameof(GamePanel), UILayer.Common);

            GUIManager.LoadPanel(nameof(TipPanel), UILayer.Top);
        }

        protected override void LaunchInProductionMode()
        {
            // 生产逻辑
            GUIManager.SetResolution(1920, 1080, 0.0f);

            GUIManager.LoadPanel(nameof(GamePanel), UILayer.Common);

            GUIManager.LoadPanel(nameof(TipPanel), UILayer.Top);
        }

        private GameObject CreateEnemy()
        {
            var enemy = Instantiate(enemyPrefab, enemyPanel.transform);
            enemy.GetComponent<Enemy>().ReleaseAction += () =>
            {
                GameModel.Instance.Score++;
                MsgDispatcher.Send(EventConfig.ScoreChange);

                PoolManager.Instance.EnemyPool.Release(enemy);
            };

            return enemy;
        }

        private void GetEnemy(GameObject enemy)
        {
            enemy.SetActive(true);
            enemy.GetComponent<Enemy>().ResetData();
            _enemys.Add(enemy);
        }

        private void ReleaseEnemy(GameObject enemy)
        {
            enemy.SetActive(false);
            _enemys.Remove(enemy);
        }

        /// <summary>
        ///     检查怪物数量，不足，则创建
        /// </summary>
        private void CheckEnemys()
        {
            if (_enemys.Count >= GameConfig.EnemyNum) return;

            PoolManager.Instance.EnemyPool.Get();
        }

        private void OnOpenSetPanel()
        {
            GUIManager.LoadPanel(nameof(SetPanel), UILayer.Common);
        }

        /// <summary>
        ///     游戏结束
        /// </summary>
        private void OnGameOver()
        {
            GameModel.Instance.OnGameOver();

            GUIManager.LoadPanel(nameof(GameOverPanel), UILayer.Common);

            // 清理怪物
            for (var i = _enemys.Count - 1; i >= 0; i--)
            {
                var enemy = _enemys[i];
                PoolManager.Instance.EnemyPool.Release(enemy);
            }
        }

        /// <summary>
        ///     游戏重开
        /// </summary>
        public void GameRestart()
        {
            GameModel.Instance.GameRestart();

            HeroModel.Instance.ResetData();

            MsgDispatcher.Send(EventConfig.GameRestart);
        }

        /// <summary>
        ///     获取 英雄 坐标
        /// </summary>
        /// <returns></returns>
        public Vector3 GetHeroPos()
        {
            return hero.GetComponent<Hero>().GetHeroPos();
        }

        /// <summary>
        ///     获取英雄模型
        /// </summary>
        /// <returns></returns>
        public GameObject GetHeroModel()
        {
            return hero.GetComponent<Hero>().GetModel();
        }

        /// <summary>
        ///     释放技能，处理与敌人交互的逻辑
        /// </summary>
        public void OnReleaseSkill(int order)
        {
            if (!GameModel.Instance.IsGaming) return;

            var skillData = HeroModel.Instance.GetSkillData(order);

            HeroModel.Instance.OnReleaseSkill(order, skillData);

            MsgDispatcher.Send(EventConfig.HeroReleaseSkill, order);

            var heroPos = GetHeroPos();
            for (var i = _enemys.Count - 1; i >= 0; i--)
            {
                var enemy = _enemys[i];
                enemy.GetComponent<Enemy>().CheckSkillHit(heroPos, skillData);
            }
        }

        /// <summary>
        ///     英雄受击
        /// </summary>
        public void OnHeroHit(EnemyData enemyData)
        {
            if (!GameModel.Instance.IsGaming) return;

            HeroModel.Instance.OnHit(enemyData);

            MsgDispatcher.Send(EventConfig.HeroHit);

            if (HeroModel.Instance.Data.Attr.CurHp <= 0) OnGameOver();
        }
    }
}